/* 高德地图 SDK 动态加载与定位工具 */

// 高德地图类型声明
declare global {
  interface Window {
    AMap: any;
  }
}

export type AMapSDK = typeof window.AMap

let sdkLoadingPromise: Promise<AMapSDK> | null = null

function loadAMapSDK(apiKey: string, securityJsCode?: string): Promise<AMapSDK> {
	if ((window as any).AMap) {
		return Promise.resolve((window as any).AMap)
	}
	if (sdkLoadingPromise) return sdkLoadingPromise

	if (securityJsCode) {
		;(window as any)._AMapSecurityConfig = { securityJsCode }
	}

	sdkLoadingPromise = new Promise((resolve, reject) => {
		const script = document.createElement('script')
		script.type = 'text/javascript'
		script.async = true
		script.src = `https://webapi.amap.com/maps?v=2.0&key=${apiKey}`
		script.onload = () => resolve((window as any).AMap)
		script.onerror = () => reject(new Error('AMap SDK 加载失败'))
		document.head.appendChild(script)
	})

	return sdkLoadingPromise
}

export interface LocationResult {
	city: string
	province?: string
	district?: string
	lnglat?: [number, number]
}

export async function locateCity(options?: {
	apiKey?: string
	securityJsCode?: string
	timeoutMs?: number
}): Promise<LocationResult> {
	// 默认后备 Key（如果未配置环境变量也能运行）
	const defaultKey = '98b1de11979880767b5a1567fd8ba1ad'
	const defaultSec = '40d32b0a893cb82a4daec5dfce5e2be6'
	const apiKey = options?.apiKey || (import.meta as any).env?.VITE_AMAP_KEY || defaultKey
	const securityJsCode = options?.securityJsCode || (import.meta as any).env?.VITE_AMAP_SEC || defaultSec
	if (!apiKey) throw new Error('缺少高德 Key，请配置 VITE_AMAP_KEY')

	const AMap = await loadAMapSDK(apiKey, securityJsCode)

	return new Promise<LocationResult>((resolve, reject) => {
		AMap.plugin(['AMap.Geolocation', 'AMap.Geocoder'], () => {
			const geolocation = new AMap.Geolocation({
				enableHighAccuracy: true,
				timeout: options?.timeoutMs ?? 10000,
			})
			geolocation.getCurrentPosition((status: string, result: any) => {
				if (status !== 'complete' || !result?.position) {
					reject(new Error('定位失败'))
					return
				}
				const position = result.position
				const lnglat: [number, number] = [position.lng, position.lat]
				const geocoder = new AMap.Geocoder()
				geocoder.getAddress(lnglat, (codeStatus: string, geocodeResult: any) => {
					if (codeStatus === 'complete' && geocodeResult?.regeocode) {
						const comp = geocodeResult.regeocode.addressComponent || {}
						const cityRaw: string = comp.city || comp.province || ''
						const city = normalizeCityName(cityRaw)
						resolve({ city, province: comp.province, district: comp.district, lnglat })
					} else {
						reject(new Error('逆地理编码失败'))
					}
				})
			})
		})
	})
}

export function normalizeCityName(name: string): string {
	if (!name) return ''
	return name.replace(/市$/u, '')
}


